package cn.funeralobjects.upms.extension.mapping;

import cn.funeralobjects.upms.extension.model.HandlerMethodMapping;
import cn.funeralobjects.upms.extension.util.ApiRequestMappingUtils;
import cn.funeralobjects.upms.model.Api;
import lombok.Getter;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.method.RequestMappingInfo;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 基本的API的范围mapping值
 *
 * @author FuneralObjects
 * Create date: 2020/5/3 12:01 PM
 */
public abstract class BaseApiHandleMapping extends RequestMappingHandlerMapping {
    /**
     * 范围值
     */
    @Getter
    private final String scope;
    /**
     * 根据 HandlerMethodMapping 对象创建名称的方法
     */
    @Getter
    private final Function<HandlerMethodMapping, String> createNameFun;

    public BaseApiHandleMapping(String scope, Function<HandlerMethodMapping, String> createNameFun) {
        Assert.hasLength(scope, "The constructor arg that scope of ApiHandleMapping must have length.");
        this.scope = scope;
        Assert.notNull(createNameFun, "The constructor arg that createNameFun of ApiHandleMapping must have length.");
        this.createNameFun = createNameFun;
    }

    @Override
    protected void handlerMethodsInitialized(@NonNull Map<RequestMappingInfo, HandlerMethod> handlerMethods) {
        super.handlerMethodsInitialized(handlerMethods);
        List<Api> apiList = handlerMethods.entrySet().stream().map(e -> {
            String name = createNameFun.apply(new HandlerMethodMapping().setMapping(e.getKey()).setMethod(e.getValue()));
            return ApiRequestMappingUtils.toHttpApi(scope, name, e.getKey());
        }).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        handlerApiInitialized(apiList);
    }

    /**
     * 用于继承处理初始化后的handler
     *
     * @param apis api集合
     */
    protected abstract void handlerApiInitialized(List<Api> apis);


}
